﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

using Oracle.ManagedDataAccess.Client;
using WFL.Data.Oracle;

namespace WFL.RBAC.Oracle
{
    public class ResourceDAL : BaseDAL, IResource
    {

        #region 接口方法

        public void Create(Resource item)
        {
            OnCreate(item);
        }

        public void Delete(int id)
        {
            OnDelete(id);
        }

        public void Update(Resource item)
        {
            OnUpdate(item);
        }

        public IList<Resource> GetList(string name, int pageIndex, int pageSize)
        {
            return OnGetList(name, pageIndex, pageSize);
        }

        public Resource Get(int id)
        {
            return OnGet(id);
        }

        public Resource GetByName(string name)
        {
            return OnGet(name);
        }

        public Resource GetByTypeName(string typeName)
        {
            return OnGetByTypeName(typeName);
        }

        public ResourceLimit GetResourceLimit(int id, string limitResourceTypeName)
        {
            return OnGetResourceLimit(id, limitResourceTypeName);
        }

        public IList<ResourceLimit> GetResourceLimitList(int id)
        {
            return OnGetResourceLimitList(id);
        }

        public IList<ResourceLimit> GetResourceLimitChain(int id, int limitId)
        {
            return OnGetResourceLimitChain(id, limitId);
        }

        #endregion

        #region 虚方法

        protected virtual void OnCreate(Resource item)
        {
            Orm.Insert<Resource>(item);
        }

        protected virtual void OnDelete(int id)
        {
            Orm.Delete<Resource>(id);
        }

        protected virtual void OnUpdate(Resource item)
        {
            Orm.Update<Resource>(item);
        }

        protected virtual IList<Resource> OnGetList(string name, int pageIndex, int pageSize)
        {
            string condition = "name like :Name";
            OracleParameter[] parameters = new OracleParameter[]
            {
                new OracleParameter("Name","%"+name+"%"),
            };
            return Orm.SelectListByPage<Resource>(condition, parameters, null, pageIndex, pageSize);
        }

        protected virtual Resource OnGet(int id)
        {
            return Orm.Select<Resource>(id);
        }

        protected virtual Resource OnGet(string name)
        {
            string condition = "name=:Name";
            OracleParameter[] parameters = new OracleParameter[]
            {
                new OracleParameter("Name",name),
            };
            IList<Resource> list = Orm.SelectList<Resource>(condition, parameters, null);
            if (list == null && list.Count == 0)
            {
                return null;
            }
            return list[0];
        }

        protected virtual Resource OnGetByTypeName(string typeName)
        {
            string condition = "typeName=:TypeName";
            OracleParameter[] parameters = new OracleParameter[]
            {
                new OracleParameter("TypeName",typeName),
            };
            IList<Resource> list = Orm.SelectList<Resource>(condition, parameters, null);
            if (list == null && list.Count == 0)
            {
                return null;
            }
            return list[0];
        }

        protected virtual ResourceLimit OnGetResourceLimit(int id, string limitResourceTypeName)
        {
            string sql = @"select rl.ResourcePropertyName,rl.LimitResourceId,rl.LimitResourcePropertyName
from ResourceLimits rl join Resources r on r.id=rl.LimitResourceId
where r.TypeName=:typeName and rl.ResourceId=:id";
            OracleParameter[] parameters = new OracleParameter[]
                {
                    new OracleParameter("typeName",limitResourceTypeName),
                    new OracleParameter("id",id)
                };
            OracleDataReaderExtension readerEx = ExecuteReaderExtension(sql, parameters);
            try
            {
                if (readerEx.Reader.Read())
                {
                    ResourceLimit item = new ResourceLimit();
                    item.ResourceId = id;
                    item.ResourcePropertyName = readerEx.Reader[0].ToString();
                    item.LimitId = Convert.ToInt32(readerEx.Reader[1]);
                    item.LimitPropertyName = readerEx.Reader[2].ToString();
                    return item;
                }
                return null;
            }
            finally
            {
                readerEx.Close();
                readerEx = null;
            }
        }

        protected virtual IList<ResourceLimit> OnGetResourceLimitList(int id)
        {
            string condition = "resourceId=:ResourceId";
            OracleParameter[] parameters = new OracleParameter[]
            {
                new OracleParameter("ResourceId",id),
            };
            return Orm.SelectList<ResourceLimit>(condition, parameters, null);
        }

        protected virtual IList<ResourceLimit> OnGetResourceLimitChain(int id, int limitId)
        {
            string sql = @"select rl.ResourceId,rl.ResourcePropertyName,rl.LimitResourceId,rl.LimitResourcePropertyName from ResourceLimits rl
start with rl.ResourceId=:ResourceId
connect by prior rl.LimitResourceId=rl.ResourceId and rl.ResourceId!=:LimitResourceId
order by level";
            OracleParameter[] parameters = new OracleParameter[]
            {
                new OracleParameter("ResourceId",id),
                new OracleParameter("LimitResourceId",limitId)
            };
            OracleDataReaderExtension readerEx = ExecuteReaderExtension(sql, parameters);
            try
            {
                if (readerEx.Reader.Read())
                {
                    IList<ResourceLimit> list = new List<ResourceLimit>();
                    do
                    {
                        ResourceLimit item = new ResourceLimit();
                        item.ResourceId = Convert.ToInt32(readerEx.Reader[0]);
                        item.LimitPropertyName = readerEx.Reader[1].ToString();
                        item.LimitId = Convert.ToInt32(readerEx.Reader[2]);
                        item.LimitPropertyName = readerEx.Reader[3].ToString();
                        list.Add(item);
                    }
                    while (readerEx.Reader.Read());
                    return list;
                }
                return null;
            }
            finally
            {
                readerEx.Close();
            }
        }

        #endregion

    }
}
